\section{Euler 1D Parallel Tests API}

In subsections \ref{subsec:caf} and \ref{subsec:openmp} it has been proved that FOODIE usage does not penalize the parallel scaling of an equivalent procedural code implemented without FOODIE. To this aim, we have solved the Euler's conservation laws (in one dimension) by means of FOODIE: as a matter of fact, Euler 1D PDEs constitutes a complex test retaining many difficulties of real applications, but it is still simple enough to serve as benchmark test. In this section we report the implementation details of the codes developed to solve (with serial and parallel models) the Euler 1D PDEs system.

\subsection{Euler 1D baseline API}\label{subsec:euler-1D-API}

The 1D Euler PDEs system is a non linear, hyperbolic (inviscid) system of conservation laws for compressible gas dynamics, that reads
\begin{equation}
\begin{matrix}
U_t = R(U)  \Leftrightarrow U_t = F(U)_x \\
U = \begin{bmatrix}
\rho \\
\rho u \\
\rho E
\end{bmatrix}\;\;\;
F(U) = \begin{bmatrix}
\rho u \\
\rho u^2 + p \\
\rho u H
\end{bmatrix}
\end{matrix}
\label{eq:euler-1D}
\end{equation}
where $\rho$ is the density, $u$ is the velocity, $p$ the pressure, $E$ the total internal specific energy and $H$ the total specific enthalpy. The PDEs system must completed with the proper initial and boundary conditions. Moreover, an ideal (thermally and calorically perfect) gas is considered
\begin{equation}
\begin{matrix}
R = c_p - c_v \\
\gamma = \frac{c_p}{c_v}\\
e = c_v T \\
h = c_p T
\end{matrix}
\end{equation}
where $R$ is the gas constant, $c_p$ and $c_v$ are the specific heats at constant pressure and volume (respectively), $e$ is the internal energy, $h$ is the internal enthalpy and *T* is the temperature. The following addition equations of state hold:
\begin{equation}
\begin{matrix}
T = \frac{p}{\rho R} \\
E = \rho e + \frac{1}{2} \rho u^2 \\
H = \rho h + \frac{1}{2} \rho u^2 \\
a = \sqrt{\frac{\gamma p}{\rho}}
\end{matrix}
\end{equation}

An extension of the above Euler system is considered allowing the modelling of a multi-fluid mixture of different gas (with different physical characteristics). The well known Standard Thermodynamic Model is used to model the gas mixture replacing the density with the density fraction of each specie composing the mixture. This led to the following system:
\begin{equation}
\begin{matrix}
U_t = R(U)  \Leftrightarrow U_t = F(U)_x \\
U = \begin{bmatrix}
\rho_s \\
\rho u \\
\rho E
\end{bmatrix}\;\;\;
F(U) = \begin{bmatrix}
\rho_s u \\
\rho u^2 + p \\
\rho u H
\end{bmatrix}\;\;\; for\; s=1,2,...N_s \\
\rho = \sum_{s=1}^{N_s}\rho_s \\
c_p = \sum_{s=1}^{N_S} \frac{\rho_s}{\rho} c_{p,s} \quad  c_v = \sum_{s=1}^{N_S} \frac{\rho_s}{\rho} c_{v,s}
\end{matrix}
\end{equation}
where $N_s$ is the number of initial species composing the gas mixture.

\subsubsection{Memory organization}
The finite volume, Godunov's like approach is employed. Essentially, the method of Lines is used to decouple the space operator from the time one. Firstly, the space operator (the residual function of equation \ref{eq:euler-1D}) is numerically solved in order to reduce the original PDEs system to a system of ODEs that is then integrated over time by means of FOODIE solvers. Here we omit the details of the numerical models, interested readers can see \cite{}. On the contrary, some details on the memory organization is necessary to explaining the implemented API.

The conservative variables are co-located at the cell center. The cell and (inter)faces numeration is as shown in listing \ref{list:grid}.
\begin{lstlisting}[firstnumber=1,style=codesimple,caption={Numerical grid organization},label={list:grid}]
        cell   (inter)faces
         |            |
         v            v
 |----|----|-...-|----|---|---|---|-...-|-----|-----|-----|-...-|-------|-------|
 |1-Ng|2-Ng| ... |-1  | 0 | 1 | 2 | ... |  Ni | Ni+1| Ni+1| ... |Ni+Ng-1| Ni+Ng |
 |----|----|-...-|----|---|---|---|-...-|-----|-----|-----|-...-|-------|-------|
0-Ng                 -1   0   1   2    Ni-1   Ni                      Ni+Ng
\end{lstlisting}
In listing \ref{list:grid} $Ni$ is the number of finite volumes (cells) used for discretizing the domain and $Ng$ is the number of ghost cells used for imposing the left and right boundary conditions (for a total of $2Ng$ cells).
For each cell the conservative variables must be stored: this is done by means of of rank 2 array where the first index refers to the conservative variables (densities, momentum or energy) while the second index refers to the space location, namely the cell index.

The most CPU time consuming part of a finite volume scheme is the fluxes computation across the cells interfaces. Such a computation corresponds to a loop over all the cells interfaces. Listing \ref{list:pseudo-fluxes} shows a pseudo-code example of such a computation.

\begin{lstlisting}[firstnumber=1,style=code,caption={Pseudo-code example of fluxes computation},label={list:pseudo-fluxes}]
do i=0, Ni
  F(:, i) = compute_fluxes(U(:, i), U(:, i+1))
enddo
\end{lstlisting}

In the pseudo-code of listing \ref{list:pseudo-fluxes} it has been emphasized that the fluxes across an interface depends on the cells at left and right of the interface itself. The key point for the parallelization of such an algorithm is to compute the fluxes concurrently using as much as possible the parallel resources provided by the running architecture. As a consequence, the above showed loop over the whole domain is split into sub-domains (explicitly or implicitly accordingly to the parallel model adopted) and the fluxed of each sub-domain are computed concurrently.

\subsubsection{The serial API}

The conservative variables of 1D Euler's system can be easily implemented as a \emph{FOODIE integrand field} defining a concrete extension of the FOODIE \emph{integrand} type. Listing \ref{list:euler_1D_type} reports the implementation of such an integrand field that is contained into the tests suite shipped within the FOODIE library.

\begin{lstlisting}[firstnumber=1,style=code,caption={implementation of the \emph{Euler 1D integrand} type},label={list:euler_1D_type}]
type, extends(integrand) :: euler_1D
  private
  integer(I_P)                   :: ord=0     ! Space accuracy formal order.
  integer(I_P)                   :: Ni=0      ! Space dimension.
  integer(I_P)                   :: Ng=0      ! Number of ghost cells for boundary conditions handling.
  integer(I_P)                   :: Ns=0      ! Number of initial species.
  integer(I_P)                   :: Nc=0      ! Number of conservative variables, Ns+2.
  integer(I_P)                   :: Np=0      ! Number of primitive variables, Ns+4.
  real(R_P)                      :: Dx=0._R_P ! Space step.
  type(weno_interpolator_upwind) :: weno      ! WENO interpolator.
  real(R_P),    allocatable      :: U(:,:)    ! Integrand (state) variables, whole physical domain [1:Nc,1:Ni].
  real(R_P),    allocatable      :: cp0(:)    ! Specific heat cp of initial species [1:Ns].
  real(R_P),    allocatable      :: cv0(:)    ! Specific heat cv of initial species [1:Ns].
  character(:), allocatable      :: BC_L      ! Left boundary condition type.
  character(:), allocatable      :: BC_R      ! Right boundary condition type.
  integer(I_P)                   :: me=0      ! ID of this\_image().
  integer(I_P)                   :: we=0      ! Number of CAF images used.
  contains
    ! auxiliary methods
    procedure, pass(self), public :: init
    procedure, pass(self), public :: destroy
    procedure, pass(self), public :: output
    procedure, pass(self), public :: dt => compute_dt
    ! ADT integrand deferred methods
    procedure, pass(self), public :: t => dEuler_dt
    procedure, pass(lhs),  public :: local_error => euler_local_error
    procedure, pass(lhs),  public :: integrand_multiply_integrand => euler_multiply_euler
    procedure, pass(lhs),  public :: integrand_multiply_real => euler_multiply_real
    procedure, pass(rhs),  public :: real_multiply_integrand => real_multiply_euler
    procedure, pass(lhs),  public :: add => add_euler
    procedure, pass(lhs),  public :: sub => sub_euler
    procedure, pass(lhs),  public :: assign_integrand => euler_assign_euler
    procedure, pass(lhs),  public :: assign_real => euler_assign_real
    ! private methods
    procedure, pass(self), private :: primitive2conservative
    procedure, pass(self), private :: conservative2primitive
    procedure, pass(self), private :: synchronize
    procedure, pass(self), private :: impose_boundary_conditions
    procedure, pass(self), private :: reconstruct_interfaces_states
    procedure, pass(self), private :: riemann_solver
    final                          :: finalize
endtype euler_1D
\end{lstlisting}

\subsection{Euler 1D CAF Enabled API}\label{subsec:euler-1D-CAF-API}

\subsection{Euler 1D OpenMP Enabled API}\label{subsec:euler-1D-OpenMP-API}
